#include "avrlib-string.h"

int length(const char * m_string)
{	
    int len = 0;
    while(*m_string++) len++;
    return len;
}

int indexOf(const char * m_string, const char m_char, int begin)
{
	if(m_string[0] != 0)
	{
		int l = length(m_string);
		
		if((l >= begin) && (begin > -1))
		{
			for(int i = begin; i < l; i++)
			{
				if(m_string[i] == m_char)
				{
					return i;
				}
			}
		}
	}
	
	return (-1);
}

int lastIndexOf(const char * m_string, const char m_char, int begin)
{
	if(m_string[0] != 0)
	{
		int l = length(m_string);	
		for(int i = (l-1); i >= begin; i--)
		{
			if(m_string[i] == m_char)
			{
				return i;
			}
		}	
	}

	return (-1);
}

int indexOf(const char * m_string, const char * m_substring, int begin)
{
	int l = length(m_string);
	int subl = length(m_substring);
	int index = -1;

	if(l >= (subl+begin))
	{
		for(int i = begin; i < l; i++)
		{
			if(m_string[i] == m_substring[0])
			{
				index = i+1;
				for(int j = i; j < subl; j++)
				{
					if(m_string[j] != m_substring[j-i])
					{
						index = -1;
						break;
					}
				}
				if(index > -1)
				{
					break;
				}
			}
		}
	}

	if(index > -1)
	{
		return index - 1;
	}
	return -1;
}

int lastIndexOf(const char * m_string, const char * m_substring, int begin)
{
	int l = length(m_string);
	int subl = length(m_substring);
	int index = -1;

	if(l >= (subl+begin))
	{
		for(int i = begin; i < l; i++)
		{
			if(m_string[i] == m_substring[0])
			{
				index = i+1;
				for(int j = i; j < subl; j++)
				{
					if(m_string[j] != m_substring[j-i])
					{
						index = -1;
						break;
					}
				}				
			}
		}
	}

	if(index > -1)
	{
		return index - 1;
	}
	return -1;	
}

char * subString(const char * m_string, int begin, int end)
{		
	if(m_string[0] != 0)
	{
		int l = length(m_string);
		if(((begin <= l) && (end <=l)) && (begin <= end) && (begin >= 0))
		{
			char * subString = new char[end-begin];
			int j = 0;
			for(int i = begin; i < end; i++)
			{
				subString[j] = m_string[i];
				j++;
			}
			subString[j] = 0;
			return subString;
		}
	}
	return "";
}

char * subString(const char * m_string, int begin)
{			
	if(m_string[0] != 0)
	{
		int l = length(m_string);
		return subString(m_string, begin, l);
	}
	return "";
}

char * replace(const char * m_string, const char * m_str1, const char * m_str2, int begin, bool all)
{	
	if(m_string[0] != 0)
	{
		int l = length(m_string);
		int str1l = length(m_str1);
		int str2l = length(m_str2);	

		int new_l = l-(str1l-str2l);
		char * new_string = new char[new_l];
		
		int begin1 = 0;
		int end1 = indexOf(m_string, m_str1, begin);

		if(end1 < 0)
		{
			return "";
		}

		int begin2 = end1 + str1l;
		int end2 = l;

		char * part1 = subString(m_string, begin1, end1);
		char * part2 = subString(m_string, begin2, end2);

		int part2l = length(part2);

		//beginning of the m_string	
		for(int i1 = 0; i1 < end1; i1++)
		{		
			new_string[i1] = part1[i1];
		}

		//m_str2
		for(int i2 = 0; i2 < str2l; i2++)
		{		
			new_string[end1+i2] = m_str2[i2];
		}

		//rest of m_string
		for(int i3 = 0; i3 < part2l; i3++)
		{		
			new_string[end1+str2l+i3] = part2[i3];
		}
		new_string[new_l] = 0;

		if(all)
		{
			while(true)
			{
				char * tmp = replace(new_string, m_str1, m_str2, end1+str2l, false);
				int i = length(tmp);
				if(i > 0) 
				{
					new_string = tmp;
				}
				else
				{
					break;
				}
			}
		}

		return new_string;
	}
	return clone(m_string);
}

char * trimLead(const char * m_string)
{	
	if(m_string[0] != 0)
	{		
		char * str = clone(m_string);
		if(m_string[0] == ' ')
		{
			int l = length(m_string);			
			int endOfWitheSpace = 0;			
			for(int i = 0; i < l; i++)
			{
				endOfWitheSpace++;
				if(m_string[i] != ' ')
				{
					str = subString(m_string, endOfWitheSpace-1);					
					break;
				}
			}
		}		
		return str;
	}	
	return "";
}

char * trimTrail(const char * m_string)
{		
	if(m_string[0] != 0)
	{		
		int l = length(m_string);
		char * str = clone(m_string);		
		if(m_string[l-1] == ' ')
		{
			int beginOfWitheSpace = l;			
			for(int i = l-1; i >= 0; i--)
			{
				beginOfWitheSpace--;
				if(m_string[i] != ' ')
				{
					str = subString(m_string, 0, beginOfWitheSpace+1);					
					break;
				}
			}
		}		
		return str;
	}	
	return "";
}

char * trim(const char * m_string)
{
	if(m_string[0] != 0)
	{
		char * str = trimLead(m_string);
		str = trimTrail(str);
		return str;
	}
	return "";
}

char * clone(const char * m_string)
{
	if(m_string[0] != 0)
	{
		int l = length(m_string);
		char * new_string = new char[l];
		for(int i = 0; i < l; i++)
		{
			new_string[i] = m_string[i];
		}
		new_string[l] = 0;
		return new_string;
	}
	return "";
}

bool equals(const char * m_str1, const char * m_str2)
{
	if((m_str1[0] == 0) && (m_str2[0] == 0))
	{
		return true;
	}
	int l1 = length(m_str1);
	int l2 = length(m_str2);
	if(l1 == l2) 
	{
		for(int i = 0; i < l1; i++)
		{
			if(m_str1[i] != m_str2[i])
			{
				return false;
			}			
		}
		return true;
	}
	else 
	{
		return false;
	}
	return false;
}

bool equalsIgnoreCase(const char * m_str1, const char * m_str2)
{
	char * str1 = toLowerCase(m_str1);
	char * str2 = toLowerCase(m_str2);
	return equals(str1, str2);
}

char * valueOf(bool val)
{
	if(val)
	{
		return "1";
	}
	return "0";
}

char * valueOf(char val)
{
	char * str = new char[20];
    int i;
	bool positive = true;

    if(val < 0)
    {
		positive = false;
        val = -val;
    }

    i = 0;
    do
    {
        str[i++] = val % 10 + '0';
    }
    while( (val /= 10) > 0);

    if(!positive) 
	{
		str[i++] = '-';
	}
    str[i] = '\0';
    str = reverse(str);

	return str;
}

char * valueOf(short val)
{
	char * str = new char[20];
    int i;
	bool positive = true;

    if(val < 0)
    {
		positive = false;
        val = -val;
    }

    i = 0;
    do
    {
        str[i++] = val % 10 + '0';
    }
    while( (val /= 10) > 0);

    if(!positive) 
	{
		str[i++] = '-';
	}
    str[i] = '\0';
    str = reverse(str);

	return str;
}

char * valueOf(int val)
{
	char * str = new char[20];
    int i;
	bool positive = true;

    if(val < 0)
    {
		positive = false;
        val = -val;
    }

    i = 0;
    do
    {
        str[i++] = val % 10 + '0';
    }
    while( (val /= 10) > 0);

    if(!positive) 
	{
		str[i++] = '-';
	}
    str[i] = '\0';
    str = reverse(str);

	return str;
}

char * valueOf(long val)
{
	char * str = new char[20];
    int i;
	bool positive = true;

    if(val < 0)
    {
		positive = false;
        val = -val;
    }

    i = 0;
    do
    {
        str[i++] = val % 10 + '0';
    }
    while( (val /= 10) > 0);

    if(!positive) 
	{
		str[i++] = '-';
	}
    str[i] = '\0';
    str = reverse(str);

	return str;
}

char * valueOf(long long val)
{
	char * str = new char[20];
    int i;
	bool positive = true;

    if(val < 0)
    {
		positive = false;
        val = -val;
    }

    i = 0;
    do
    {
        str[i++] = val % 10 + '0';
    }
    while( (val /= 10) > 0);

    if(!positive) 
	{
		str[i++] = '-';
	}
    str[i] = '\0';
    str = reverse(str);

	return str;
}
/*
int pow(int x, int y)
{
	for(int i = 0; i < y; i++)
	{
		x = x * x;
	}
	return 0;
}
*/
char * valueOf(float val, int precision)
{
	//char * str = new char[80];
    //int i;
	long exponent;
	long fraction;
	bool positive = true;

    if(val < 0)
    {
		positive = false;
        val = -val;
    }

/*
	int j = 1;
	for(int i = 0; i < precision; i++)
	{
		j = j * 10;
	}
*/
	exponent = (long)val;	
	fraction = (long)((val - exponent) * 1000000000);

	char * str1 = valueOf(exponent);
	char * str2 = valueOf(fraction);


	//padding with zeros
	int strl2 = length(str2);
	if(strl2 < 9)
	{
		int pad = 9 - strl2;
		for(int i = 0; i < pad; i++)
		{
			str2 = append("0", str2);
		}
	}

	if(positive)
	{
		char * str = append(str1, ".");
		str = append(str, str2);

		return str;
	}
	else
	{
		char * str = append("-", str1);
		str = append(str, ".");
		str = append(str, str2);

		return str;
	}
}

char * valueOfAsWord(bool b)
{
	if(b)
	{
		return "true";
	}
	return "false";
}

char * toLowerCase(const char * m_string)
{
	if(m_string[0] != 0)
	{
		char * str = clone(m_string);
		if(m_string[0] !=0)
		{
			int l = length(m_string);
			for(int i = 0; i < l; i++)
			{
				if((m_string[i] > '@') && (m_string[i] < '['))
				{
					str[i] = m_string[i] + ' ';
				}
			}
		}
		return str;
	}
	return "";
}

char * toUpperCase(const char * m_string)
{
	if(m_string[0] != 0)
	{
		char * str = clone(m_string);
		if(m_string[0] !=0)
		{
			int l = length(m_string);
			for(int i = 0; i < l; i++)
			{
				if((m_string[i] > '`') && (m_string[i] < '{'))
				{
					str[i] = m_string[i] - ' ';
				}
			}
		}
		return str;
	}
	return "";
}

char * reverse(const char * m_string)
{
	if(m_string[0] != 0)
	{
		int i, j;
		int l = length(m_string); 
		char * str = new char[l];
		str[l] = 0;
		for(i = 0, j = (l - 1); i < l; i++, j--)
		{
			str[j] = m_string[i];
		}
		return str;
	}
	return "";
}

char * append(const char * m_str1, const char * m_str2)
{
	int strl1 = length(m_str1);
	int strl2 = length(m_str2);

	char * str = new char[strl1 + strl2];

	for(int i = 0; i < strl1; i++)
	{
		str[i] = m_str1[i];
	}

	for(int j = 0; j < strl2; j++)
	{
		str[j+strl1] = m_str2[j];
	}

	str[strl1 + strl2] = 0;

	return str;
}